package acme.bloodtime.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import modelo.ICiudadDO;
import modelo.IVampiroDO;
import modelo.IVisitaDAO;
import modelo.IVisitaDO;

import dao.api.DataObject;
import dao.api.Reference;

/**
 * 
 * @author Eduardo D. Sandoval V.
 * 
 */
public class VisitaDAO extends BloodTimeBaseDAO implements IVisitaDAO {

	public VisitaDAO() {
		// empty
	}

	public void createTable() throws SQLException {
		StringBuffer strbuf;

		// ----------------------------------------

		dropTable();
		// ----------------------------------------

		VampiroDAO vampiroDAO = new VampiroDAO();
		vampiroDAO.init(connectionBean);

		CiudadDAO ciudadDAO = new CiudadDAO();
		ciudadDAO.init(connectionBean);

		strbuf = new StringBuffer();

		strbuf.append("CREATE TABLE ");
		strbuf.append(getTableName());
		strbuf.append(" (");
		strbuf.append(VisitaDO.ID);
		strbuf.append(" SERIAL PRIMARY KEY, ");
		strbuf.append(VisitaDO.PROB_HORDAS);
		strbuf.append(" NUMERIC, ");
		strbuf.append(VisitaDO.VAMPIRO_ID);
		strbuf.append(" INT REFERENCES ");
		strbuf.append(vampiroDAO.getTableName());
		strbuf.append(", ");
		strbuf.append(VisitaDO.CIUDAD_ID);
		strbuf.append(" INT REFERENCES ");
		strbuf.append(ciudadDAO.getTableName());
		strbuf.append(")");

		System.err.println(strbuf.toString());

		connection.createStatement().execute(strbuf.toString());

	}

	// --------------------------------------------------------------------------------

	@Override
	public void insert(DataObject dataObject) throws SQLException {
		checkCache(dataObject, CHECK_INSERT);
		checkClass(dataObject, VisitaDO.class, CHECK_INSERT);

		VisitaDO visitaDO = (VisitaDO) dataObject;

		visitaDO.setId(getNextId());

		StringBuffer strbuf = new StringBuffer();

		strbuf.append("INSERT INTO ");
		strbuf.append(getTableName());
		strbuf.append(" VALUES (");
		strbuf.append(visitaDO.getId());
		strbuf.append(", ");
		strbuf.append(visitaDO.getProbHordas());
		strbuf.append(", ");
		
		Reference<IVampiroDO> vampiroIdRef = visitaDO.getVampiroId();
		vampiroIdRef.checkInsert();
		
		strbuf.append(vampiroIdRef.getIdAsString());
		strbuf.append(", ");
		
		Reference<ICiudadDO> ciudadIdRef = visitaDO.getCiudadId();
		ciudadIdRef.checkInsert();
		
		strbuf.append(ciudadIdRef.getIdAsString());
		strbuf.append(")");

		System.err.println(strbuf.toString());

		connection.createStatement().execute(strbuf.toString());

		dtaSession.add(dataObject);
	}

	// --------------------------------------------------------------------------------

	@Override
	public void update(DataObject dataObject) throws SQLException {
		checkCache(dataObject, CHECK_UPDATE);
		checkClass(dataObject, VisitaDO.class, CHECK_UPDATE);

		VisitaDO visitaDO = (VisitaDO) dataObject;

		StringBuffer strbuf = new StringBuffer();

		strbuf.append("UPDATE ");
		strbuf.append(getTableName());
		strbuf.append(" SET ");

		strbuf.append(VisitaDO.PROB_HORDAS);
		strbuf.append(" = ");
		strbuf.append(visitaDO.getProbHordas());

		strbuf.append(", ");

		strbuf.append(VisitaDO.VAMPIRO_ID);
		strbuf.append(" = ");

		Reference<IVampiroDO> vampiroIdRef = visitaDO.getVampiroId();
		vampiroIdRef.checkUpdate();
		
		strbuf.append(vampiroIdRef.getIdAsString());
		strbuf.append(", ");
		strbuf.append(VisitaDO.CIUDAD_ID);
		strbuf.append(" = ");

		Reference<ICiudadDO> ciudadIdRef = visitaDO.getCiudadId();
		ciudadIdRef.checkUpdate();
		
		strbuf.append(ciudadIdRef.getIdAsString());
		strbuf.append(" WHERE ");
		strbuf.append(VisitaDO.ID);
		strbuf.append(" = ");
		strbuf.append(visitaDO.getId());

		System.err.println(strbuf.toString());

		connection.createStatement().execute(strbuf.toString());
	}

	// --------------------------------------------------------------------------------

	@Override
	public void delete(DataObject dataObject) throws SQLException {
		checkCache(dataObject, CHECK_DELETE);
		checkClass(dataObject, VisitaDO.class, CHECK_DELETE);

		VisitaDO visitaDO = (VisitaDO) dataObject;

		StringBuffer strbuf = new StringBuffer();

		strbuf.append("DELETE FROM ");
		strbuf.append(getTableName());

		strbuf.append(" WHERE ");
		strbuf.append(VisitaDO.ID);
		strbuf.append(" = ");
		strbuf.append(visitaDO.getId());

		System.err.println(strbuf.toString());

		connection.createStatement().execute(strbuf.toString());

		dtaSession.del(dataObject);
	}

	// --------------------------------------------------------------------------------

	protected VisitaDO resultSetToDO(ResultSet rs) throws SQLException {
		VisitaDO ret = //
		(VisitaDO) dtaSession.getDtaByKey( //
				VisitaDO.class, rs.getInt(VisitaDO.ID));

		if (ret != null) {
			return ret;
		}

		ret = new VisitaDO();

		ret.setId/*     */(rs.getInt(VisitaDO.ID));
		ret.setProbHordas/*   */(rs.getFloat(VisitaDO.PROB_HORDAS));

		Reference<IVampiroDO> ref1 = new Reference<IVampiroDO>();
		ref1.setRefIdent(rs.getInt(VisitaDO.VAMPIRO_ID));

		ret.setVampiroId(ref1);

		Reference<ICiudadDO> ref2 = new Reference<ICiudadDO>();
		ref2.setRefIdent(rs.getInt(VisitaDO.CIUDAD_ID));

		ret.setCiudadId(ref2);

		return (VisitaDO) dtaSession.add(ret);
	}

	public void loadVampiroId(IVisitaDO visitaDO) throws SQLException {
		checkClass(visitaDO, VisitaDO.class, CHECK_UPDATE);

		VampiroDAO vampiroDAO = new VampiroDAO();
		vampiroDAO.init(connectionBean);

		Reference<IVampiroDO> ref = visitaDO.getVampiroId();

		// ----------------------------------------
		// If ident == 0 there is nothing to do
		// ----------------------------------------

		if (ref.getRefIdent() == 0) {
			return;
		}

		IVampiroDO vampiroDO = //
		(IVampiroDO) vampiroDAO.loadById(ref.getRefIdent());

		ref.setRefValue(vampiroDO);
	}

	public void loadCiudadId(IVisitaDO visitaDO) throws SQLException {
		checkClass(visitaDO, VisitaDO.class, CHECK_UPDATE);

		CiudadDAO ciudadDAO = new CiudadDAO();
		ciudadDAO.init(connectionBean);

		Reference<ICiudadDO> ref = visitaDO.getCiudadId();

		// ----------------------------------------
		// If ident == 0 there is nothing to do
		// ----------------------------------------

		if (ref.getRefIdent() == 0) {
			return;
		}

		CiudadDO ciudadDO = //
		(CiudadDO) ciudadDAO.loadById(ref.getRefIdent());

		ref.setRefValue(ciudadDO);
	}

	public List<IVisitaDO> listByVampiroId(int id) throws SQLException {

		StringBuffer strbuf = new StringBuffer();

		strbuf.append("SELECT * FROM ");
		strbuf.append(getTableName());

		strbuf.append(" WHERE ");
		strbuf.append(VisitaDO.VAMPIRO_ID);
		strbuf.append(" = ");
		strbuf.append(id);

		System.err.println(strbuf.toString());

		ResultSet rs = //
		connection.createStatement().executeQuery(strbuf.toString());

		List<IVisitaDO> ret = new ArrayList<IVisitaDO>();

		while (rs.next()) {
			ret.add(resultSetToDO(rs));
		}

		return ret;
	}

	public List<IVisitaDO> listByCiudadId(int id) throws SQLException {

		StringBuffer strbuf = new StringBuffer();

		strbuf.append("SELECT * FROM ");
		strbuf.append(getTableName());

		strbuf.append(" WHERE ");
		strbuf.append(VisitaDO.CIUDAD_ID);
		strbuf.append(" = ");
		strbuf.append(id);

		System.err.println(strbuf.toString());

		ResultSet rs = //
		connection.createStatement().executeQuery(strbuf.toString());

		List<IVisitaDO> ret = new ArrayList<IVisitaDO>();

		while (rs.next()) {
			ret.add(resultSetToDO(rs));
		}

		return ret;
	}

	public IVisitaDO loadByVampiroIdCiudadId(int vampiroId, int ciudadId)
			throws SQLException {

		StringBuffer strbuf = new StringBuffer();

		strbuf.append("SELECT * FROM ");
		strbuf.append(getTableName());

		strbuf.append(" WHERE ");
		strbuf.append(VisitaDO.CIUDAD_ID);
		strbuf.append(" = ");
		strbuf.append(ciudadId);
		strbuf.append(" AND ");
		strbuf.append(VisitaDO.VAMPIRO_ID);
		strbuf.append(" = ");
		strbuf.append(vampiroId);

		System.err.println(strbuf.toString());

		ResultSet rs = //
		connection.createStatement().executeQuery(strbuf.toString());

		if (rs.next()) {
			return resultSetToDO(rs);
		}

		return null;

	}
}
